﻿/***************************************************************************
 * 
 * This code is based on this article:
 *          http://justinangel.net/WindowsPhone7EmulatorAutomation
 * 
 * This program uses ICSharpCode.SharpZipLib library to unzip the XAP file
 * You'll need to add that library (freely downloadable) to the project in
 * order to compile it.
 * 
 * Program usage:
 *      
 *      WP7EmulatorLauncher.exe [/target:<option>] <yourXapFile.xap>
 *      
 *      where <option> can be 'device' or 'emulator' and
 *      wher <yourXapFile.xap> is the XAP file you want to launch
 * 
 * 
 * WP7 App Launcher
 * Copyright (C) 2011 anderZubi
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * 
 *********************************************************************************/

using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.SmartDevice.Connectivity;

namespace WP7AppLauncher
{
    class Program
    {
        static bool useEmulator = true; // Launch in emulator by default

        static string xapFile;

        static void Main(string[] args)
        {
            int argsCount = args.Length;
            

            switch (argsCount)
            {
                case 0:
                    ShowHelp();
                    break;
                case 1:
                    xapFile = args[0];
                    LaunchApp();
                    break;
                case 2:
                    ProcessOptions(args);
                    break;
                default:
                    ProcessOptions(args);
                    break;
            }
        }

        private static void ProcessOptions(string[] args)
        {
            if (args[0] == "/target:device")
                useEmulator = false;
            else if (args[0] == "/target:emulator")
                useEmulator = true;
            else
            {
                throw new Exception("Exception: option not recognized: " + args[0]);
                
            }
            xapFile = args[args.Length - 1];
            LaunchApp();
        }

        private static void LaunchApp()
        {
            try
            {
                string extractionPath = UnzipToTemporary(xapFile);
                Console.WriteLine("Created a temporary directory to extract content at: " + extractionPath);

                // Get CoreCon WP7 SDK
                DatastoreManager dsmgrObj = new DatastoreManager(1033);
                Platform WP7SDK = dsmgrObj.GetPlatforms().Single(p => p.Name == "Windows Phone 7");

                // Get Emulator / Device
                Device WP7Device = null;
                if (useEmulator)
                {
                    try
                    {
                        WP7Device = WP7SDK.GetDevices().Single(d => d.Name == "Windows Phone 7 Emulator"); // 7.0 Emulator
                    }
                    catch (Exception e)
                    {
                        try
                        {
                            WP7Device = WP7SDK.GetDevices().Single(d => d.Name == "Windows Phone Emulator"); // 7.1 Emulator
                        }
                        catch (Exception ex)
                        {
                           
                        }
                    }
                }
                else
                    WP7Device = WP7SDK.GetDevices().Single(d => d.Name == "Windows Phone Device");

                // Connect to WP7 Emulator / Device
                Console.WriteLine("Connecting to Windows Phone 7 Emulator/Device...");
                WP7Device.Connect();
                Console.WriteLine("Windows Phone 7 Emulator/Device Connected...");

                Guid appID = GetAppID(extractionPath + Path.DirectorySeparatorChar + "WMAppManifest.xml");

                RemoteApplication app;
                if (WP7Device.IsApplicationInstalled(appID))
                {
                    Console.WriteLine("Uninstalling sample XAP to Windows Phone 7 Emulator/Device...");
                    app = WP7Device.GetApplication(appID);
                    app.Uninstall();
                    Console.WriteLine("Sample XAP Uninstalled from Windows Phone 7 Emulator/Device...");
                }

                // Install XAP
                Console.WriteLine("Installing sample XAP to Windows Phone 7 Emulator/Device...");

                string iconPath = extractionPath + @"\ApplicationIcon.png";

                app = WP7Device.InstallApplication(appID, appID, "NormalApp", iconPath, xapFile);
                Console.WriteLine("Sample XAP installed to Windows Phone 7 Emulator...");

                // Launch Application 
                Console.WriteLine("Launching sample app on Windows Phone 7 Emulator...");
                app.Launch();

                Console.WriteLine("Launched sample app on Windows Phone 7 Emulator...");
                Directory.Delete(extractionPath, true);
                Console.WriteLine("Deleted the temporary directory at: " + extractionPath);
            }
            catch (Exception e)
            {
                Console.WriteLine("Exception: " + e.Message);
            }
        }

        private static void ShowHelp()
        {
            // To do
        }

        static string UnzipToTemporary(string xapFileName)
        {
             string windowsTempPath = Path.GetTempPath();
                string extractionFolder = windowsTempPath + Path.DirectorySeparatorChar + Path.GetRandomFileName();

            try
            {             
                ICSharpCode.SharpZipLib.Zip.FastZip fZ = new ICSharpCode.SharpZipLib.Zip.FastZip();
                fZ.ExtractZip(xapFileName, extractionFolder, "");
                Console.WriteLine("Contents of XAP file extracted to: " + extractionFolder);
                return extractionFolder;
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        static Guid GetAppID(string appManifestFile)
        {
            Guid guid = new Guid();

            using (StreamReader sReader = new StreamReader(File.Open(appManifestFile, FileMode.Open)))
            {
                Regex regex = new Regex(@"(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})");

                bool idFound = false;
                string currentLine = sReader.ReadLine();


                while (!idFound && currentLine != null)
                {
                    Match m = regex.Match(currentLine);
                    if (m.Success)
                    {
                        idFound = true;
                        Guid.TryParse(m.Value, out guid);
                        break;
                    }
                    currentLine = sReader.ReadLine();
                }
            }

            Console.WriteLine("AppID: " + guid.ToString());
            return guid;
        }
    }
}
